<template>
  <div class="doc-camera" v-loading="uploading"
       element-loading-text="文件生成中..."
       element-loading-spinner="el-icon-loading"
       element-loading-background="rgba(0, 0, 0, 0.4)"
  >
    <div class="camera-view">
      <canvas id="camera_canvas" ref="camera_canvas"></canvas>
    </div>
    <div class="camera-tool">
      <div class="top_tool">
        <slot name="topTool">
        </slot>
      </div>
      <text v-for="item in info">
        {{ item }}
      </text>
      <el-select v-model="resolution" placeholder="分辨率" @change="resolutionChange">
        <el-option
            v-for="(item,i) in resolutions"
            :key="i+'_'+item[0]+'*'+item[1]"
            :label="item[0]+'*'+item[1]"
            :value="item">
        </el-option>
      </el-select>
      <el-button-group>
        <el-button type="primary" size="mini" icon="el-icon-refresh-left" @click="rotateL"/>
        <el-button type="primary" size="mini" icon="el-icon-refresh-right" @click="rotateR"/>
      </el-button-group>
      <el-button-group>
        <el-button type="primary" size="mini" icon="el-icon-zoom-in" @click="zoomIn"/>
        <el-button type="primary" size="mini" icon="el-icon-zoom-out" @click="zoomOut"/>
      </el-button-group>
      <el-button size="mini" :type="cutType===0?'primary':'default'" icon="el-icon-full-screen"
                 @click="cutTypeChange">
        裁切
      </el-button>
      <el-button type="primary" size="mini" icon="el-icon-camera" @click="capture" :loading="uploading">拍照</el-button>
      <el-dropdown>
        <el-button size="mini" icon="el-icon-setting">更多</el-button>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item>
            <el-upload :action="uploadApi" :headers="headers"
                       :show-file-list="false" :on-success="uploadSuccess"
            >
              <el-button size="small">
                选择
                <i class="el-icon-upload el-icon--right"></i>
              </el-button>
            </el-upload>
          </el-dropdown-item>
          <slot #more-tool></slot>
        </el-dropdown-menu>
      </el-dropdown>
    </div>
    <div class="image_preview" v-if="imgPreview">
      <el-image :src="picture" class="preview_img" fit="contain"></el-image>
      <i class="preview_close el-icon-circle-close" @click="cancelUpload"></i>
      <el-button class="upload_button" type="primary" round @click="confirmUpload" icon="el-icon-upload">确认
      </el-button>
    </div>
  </div>
</template>
<script>

import camera from "./js";
import {EventBus} from "@/main";
import {getToken} from "@/utils/auth";
import {uploadBase64} from "@/utils/request";

export default {
  name: "DocCamara",
  emits: ['photograph', 'upload'],
  props: {
    autoUpload: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      uploadApi: process.env.VUE_APP_BASE_API + "/system/oss/upload",
      headers: {
        Authorization: "Bearer " + getToken()
      },
      uploading: false,
      imgPreview: false,
      camera: undefined,
      resolutions: [],
      devNames: [],
      info: [],
      picture: undefined,
      cutType: 1,
      cameraId: 0,
      resolution: []
    }
  },
  methods: {
    onLister() {
      EventBus.$on("camera.loadOver", ws => {
        console.log("loadOver")
        //初始化连接完成后操作
        this.camera.webSocket = ws;
        this.openCamera(1920, 1080);
        this.camera.onlyBase64();
        this.rotateR();
      })
      EventBus.$on("camera.mainDevId", (mainDevId) => {
        this.cameraId = mainDevId;
      })

      EventBus.$on("camera.getPicBase64", base64 => {
        this.picture = 'data:;base64,' + base64;
        if (this.autoUpload) {
          this.upload();
        } else {
          this.imgPreview = true;
        }
      })

      EventBus.$on("camera.setResolution", ([width, height]) => {
        this.resolution = [width, height];
        console.log("设置分辨率成功", [width, height])
      })

      EventBus.$on("camera.resolution", resolution => {
        this.resolutions = resolution.sort((a, b) => {
          return b[0] * b[1] - a[0] * a[1];
        });
      })

      EventBus.$on("camera.devNames", devNames => {
        this.devNames = devNames
      })

      EventBus.$on("camera.info", info => {
        this.info.push(info)
        if (this.info.length > 5) {
          this.info.shift();
        }
      })

      EventBus.$on("camera.capture", base64 => {
        //拍照成功
        this.picture = 'data:image/jpg;base64,' + base64;
        if (this.autoUpload) {
          this.upload()
        } else {
        }
      })
    },
    confirmUpload() {
      this.upload()
    },
    cancelUpload() {
      this.picture = undefined;
    },
    async upload() {
      this.uploading = true;
      uploadBase64(this.picture, new Date().getTime() + ".jpg").then(response => {
        this.uploadSuccess(response)
      }).catch(() => {
        this.uploading = false;
        this.$message.error("上传失败");
      })
    },
    uploadSuccess(response) {
      this.uploading = false
      this.imgPreview = false;
      this.$emit('upload', response.data)
    },
    init() {
      //初始化连接
      if (!!window.ActiveXObject || "ActiveXObject" in window) {
        alert("您的浏览器不支持Active")
        return;
      }
      if (!window.WebSocket) {
        alert("您的浏览器不支持webSocket连接高拍仪！");
        return;
      }
      this.camera = camera.create(this.$refs.camera_canvas, "localhost");
      this.camera.connect();
    },
    capture() {
      this.camera.captureImage();
    },
    resolutionChange() {
      this.camera.setResolution(this.cameraId, this.resolution[0], this.resolution[1]);
    },
    rotateL() {
      this.camera.rotateL();
    },
    rotateR() {
      this.camera.rotateR();
    },
    zoomIn() {
      this.camera.zoomIn();
    },
    zoomOut() {
      this.camera.zoomOut();
    },
    cutTypeChange() {
      this.camera.setCutType(this.cutType);
      this.cutType = this.cutType === 0 ? 1 : 0;
    },
    openCamera(width, height) {
      this.camera.startVideo(this.cameraId, width, height);
    }
  },
  created() {
    this.onLister();
    this.$nextTick(() => {
      this.init()
    });
  },
  destroyed() {
    EventBus.$off("camera.loadOver");
    EventBus.$off("camera.mainDevId");
    EventBus.$off("camera.getPicBase64");
    EventBus.$off("camera.setResolution");
    EventBus.$off("camera.resolution");
    EventBus.$off("camera.devNames");
    EventBus.$off("camera.info");
    EventBus.$off("camera.capture");
    this.camera.close()
  }
}
</script>
<style lang="scss" scoped>
.doc-camera {
  width: 100%;
  height: 100%;
  border-radius: 10px;
  display: flex;
  flex-shrink: 0;

  .camera-view {
    //width: calc(100% - 120px);
    height: 100%;
    border-radius: 10px;
    background-color: aliceblue;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;


    #camera_canvas {
      height: 100% !important;
      width: 100% !important;
      background-color: gainsboro;
    }
  }

  @supports (aspect-ratio: 210/297) {
    .camera-view {
      padding: 0;
      aspect-ratio: 210/297;
    }
  }

  .camera-tool {
    padding: 10px;
    width: 120px;
    height: 100%;
    display: flex;
    display: -webkit-flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-content: center;
    align-items: center;
    margin: 5px;
    justify-content: flex-end;
    border-radius: 10px;

    .el-button + .el-button {
      margin: 0;
    }
  }

  .top_tool {
    position: absolute;
    top: 20px;
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-start;


  }

  .image_preview {
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    background-color: rgb(0 0 0 / 57%);
    width: 100%;
    height: 100%;
    z-index: 99999;

    .preview_img {
      width: calc(100% - 100px);
      height: 100%;
    }

    .preview_close {
      text-shadow: 0 0 3px black;
      width: 40px;
      height: 40px;
      font-size: 40px;
      position: absolute;
      right: 10px;
      top: 10px;
      color: white;
    }

    .upload_button {
      position: absolute;
      left: calc(50% - 100px);
      bottom: 20px;
    }
  }
}

</style>